package com.minelx.util.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import static java.util.Arrays.stream;

public class RClass<T> {

	private final Class<T> target;

	private RClass(Class<T> target) {
		this.target = target;
	}

	public T newInstance(Object... args) {
		try {
			Class<?>[] classesOfArgs = stream(args).map(Object::getClass).toArray(Class[]::new);
			Constructor<T> constructor = target.getConstructor(classesOfArgs);
			return constructor.newInstance(args);
		} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
			throw new IllegalStateException("failed to create instance.", e);
		}
	}

//	public T newInstance() {
//		try {
//			return target.newInstance();
//		} catch (InstantiationException | IllegalAccessException e) {
//			throw new IllegalStateException("failed to create instance.", e);
//		}
//	}

	public static <T> RClass<T> of(Class<T> target) {
		return new RClass<>(target);
	}

	@SuppressWarnings("unchecked")
	public static <T> RClass<T> className(String className) {
		try {
			return of((Class<T>) Class.forName(className));
		} catch (ClassNotFoundException e) {
			throw new IllegalArgumentException("no such class: " + className, e);
		}
	}
}
